/* global Cesium */
const createGuid = Cesium.createGuid;
const defaultValue = Cesium.defaultValue;
const Cartesian3 = Cesium.Cartesian3;
const Color = Cesium.Color;
const BillboardCollection = Cesium.BillboardCollection;
const ScreenSpaceEventHandler = Cesium.ScreenSpaceEventHandler;
const ScreenSpaceEventType = Cesium.ScreenSpaceEventType;

import DrawHelper from './DrawHelper';
import carToDegrees from './carToDegrees';

export default class Marker extends BillboardCollection {
    constructor(options) {
        super({
            scene: options.scene,
        });
        super.add(options);
        this.id = defaultValue(options.id, createGuid());
        this.properties = defaultValue(options.properties, {});
        this.enEdit = defaultValue(options.enEdit, true);
        this.listeners = defaultValue(options.listeners, {});
        this._primitives = defaultValue(options.primitives, undefined);
        this._createPrimitive = false;
        let C = this._billboards[0].color;
        this._color =
            'rgba(' +
            C.red * 255 +
            ',' +
            C.green * 255 +
            ',' +
            C.blue * 255 +
            ',' +
            C.alpha +
            ')';
    }

    destroy() {
        this.removeAll();
        this._primitives.remove(this);
    }

    // set show(flag) {
    //     this._billboards[0].show = flag;
    // }

    getType() {
        return 'Marker';
    }

    update(context) {
        super.update(context);
        if (this._createPrimitive) {
            this._createPrimitive = false;
            this._mountEventListener(this._billboards[0]);
        }
    }

    get position() {
        let position = carToDegrees(this._billboards[0].position);
        let _self = this;
        return new Proxy(position, {
            set: function(obj, prop, value) {
                obj[prop] = value;
                _self._billboards[0].position = Cartesian3.fromDegrees(
                    obj.lon,
                    obj.lat
                );
                return true;
            },
        });
    }

    set position(value) {
        this._billboards[0].position = Cartesian3.fromDegrees(
            value.lon,
            value.lat
        );
    }

    get image() {
        return this._billboards[0].image;
    }
    set image(value) {
        this._billboards[0].image = value;
    }

    get color() {
        return this._color;
    }
    set color(value) {
        this._color = value;
        this._billboards[0].color = Color.fromCssColorString(value);
    }

    get scale() {
        return this._billboards[0].scale;
    }
    set scale(value) {
        this._billboards[0].scale = value;
    }
    set listeners(value) {
        let _self = this;
        this._listeners = new Proxy(value, {
            get: function(target, key, proxy) {
                if (key === 'leftClick' && _self.enEdit) {
                    return function() {
                        target[key] && target[key](...arguments);
                        _self.setEditMode(true);
                    };
                }
                return target[key];
            },
        });
    }

    get listeners() {
        return this._listeners;
    }

    _mountEventListener(primitive) {
        Object.assign(primitive, this.listeners);
    }

    addEventListener(type, func) {
        this.listeners[type] = func;
        this._primitive && (this._primitive[type] = this.listeners[type]);
        this._outlinePrimitive &&
            (this._outlinePrimitive[type] = this.listeners[type]);
    }

    removeEventListener(type) {
        this.listeners[type] = null;
        this._primitive && (this._primitive[type] = this.listeners[type]);
        this._outlinePrimitive &&
            (this._outlinePrimitive[type] = this.listeners[type]);
    }

    setEditMode(editMode) {
        if (this._editMode === editMode) {
            return;
        }
        if (editMode) {
            this._editMode = true;
            let _self = this;
            let scene = this._scene;
            DrawHelper.setEdited(this);
            let options = null;
            if (typeof this.startEditCallback === 'function') {
                options = {
                    // image: this.image,
                    color: this.color,
                    scale: this.scale,
                    position: this.position,
                };
                let primitiveAttr = new Proxy(options, {
                    set: function(obj, prop, value) {
                        obj[prop] = value;
                        _self[prop] = value;
                        return true;
                    },
                });
                this.startEditCallback(primitiveAttr, this);
            }

            const enableRotation = function(enable) {
                scene.screenSpaceCameraController.enableRotate = enable;
                scene.screenSpaceCameraController.enableTranslate = enable;
            };
            this._billboards[0]['leftDown'] = function() {
                function onDrag(position) {
                    _self._billboards[0].position = position;
                    options.position = _self.position;
                }

                function onDragEnd() {
                    handler.destroy();
                    enableRotation(true);
                }
                let handler = new ScreenSpaceEventHandler(scene.canvas);
                handler.setInputAction(function(movement) {
                    let ray = scene.camera.getPickRay(movement.endPosition);
                    let cartesian = scene.globe.pick(ray, _self._scene);
                    if (cartesian) {
                        onDrag(cartesian);
                    } else {
                        onDragEnd(cartesian);
                    }
                }, ScreenSpaceEventType.MOUSE_MOVE);
                handler.setInputAction(function(movement) {
                    onDragEnd();
                }, ScreenSpaceEventType.LEFT_UP);
                handler._buttonDown[0] = true;

                enableRotation(false);
            };
            this._globeClickHandler = new ScreenSpaceEventHandler(scene.canvas);
            this._globeClickHandler.setInputAction(function(movement) {
                let pickedObject = scene.pick(movement.position);
                if (!(pickedObject && pickedObject.primitive)) {
                    DrawHelper.disableAllEditMode();
                }
            }, ScreenSpaceEventType.LEFT_CLICK);
        } else {
            if (typeof this.endEditCallback === 'function') {
                this.endEditCallback(this);
            }
            this._globeClickHandler && this._globeClickHandler.destroy();
            this._globeClickHandler = null;
            this._billboards[0] && (this._billboards[0]['leftDown'] = null);
            this._editMode = false;
        }
    }
}
